package wbhproject.tools;

import org.apache.log4j.Logger;

import wbhproject.model.ControllerUnit;
import wbhproject.model.MeasurePoint;
import wbhproject.tools.*;

import javax.sql.*;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URLConnection;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

import javax.naming.*;

public class MeasurePointRequestor implements Runnable {
	static Logger log = Logger.getLogger(MeasurePointRequestor.class);
	private MeasurePointRequestorController myController;
	private boolean myGoon = true;
	private Configuration myConfig;

	public MeasurePointRequestor(
			MeasurePointRequestorController measurePointRequestorController) {
		log.debug("Constuctor was called ...");
		myController = measurePointRequestorController;
		myConfig = Configuration.getInstance();
	}

	@Override
	public void run() {
		log.debug("Run was called ...");
		int cycle = 0;
		// Get database-connection
		Context envContext;
		try {
			log.debug("Try to establish database connection ...");
			envContext = new InitialContext();
			DataSource ds = (DataSource) envContext.lookup(myConfig
					.getDataSourceContext());
			Connection con = ds.getConnection();
			Statement stmt1 = con.createStatement();
			ResultSet rs1 = stmt1.executeQuery("SELECT * FROM controllerunit");
			log.debug("Running query to select all active contropller units ...");
			// Create list of measure-points
			// This is for performance-issues...
			List<MeasurePoint> mpList = new ArrayList<MeasurePoint>();
			while (rs1.next()) {
				ControllerUnit controllerUnit = new ControllerUnit(
						rs1.getLong("id"), rs1.getString("serveraddress"),
						rs1.getString("stationname"),
						rs1.getString("stationalias"), rs1.getBoolean("active"));
				log.debug("Performing registering for controllerunit: "
						+ controllerUnit.getDescription());
				Statement stmt2 = con.createStatement();
				ResultSet rs2 = stmt2
						.executeQuery("SELECT * FROM measurepoint WHERE controllerunit = "
								+ rs1.getLong("id") + "");
				while (rs2.next()) {
					log.debug("Registering measurepopint "
							+ rs2.getString("symbolname"));
					MeasurePoint measurePoint = new MeasurePoint(
							rs2.getLong("id"), 
							controllerUnit, rs2.getString("symbolname"),
							rs2.getString("registeraddress"),
							rs2.getString("cmt"), rs2.getString("format"),
							rs2.getInt("decimaldigits"));
					log.debug("Registering measurepoint: "
							+ measurePoint.getDescription());
					mpList.add(measurePoint);
				}
			}

			// Start loop
			MeasurePoint actMeasurePoint;
			String inputLine;
			long longValue;
			double doubleValue;
			String insertSQL;
			while (myGoon) {
				log.debug("Query-Cycle:" + String.valueOf(++cycle));
				// Loop around all measurepoints...
				for (int i = 0; i < mpList.size(); i++) {
					actMeasurePoint = mpList.get(i);
					log.debug("Performing request for url:"
							+ actMeasurePoint.getReadValUrl());
					URLConnection uc = actMeasurePoint.getReadValUrl()
							.openConnection();
					BufferedReader in = new BufferedReader(
							new InputStreamReader(uc.getInputStream()));
					inputLine = in.readLine();
					longValue = Long.parseLong(inputLine);
					doubleValue = MeasurePoint.getDoubleValue(actMeasurePoint,
							longValue);
					insertSQL = "INSERT INTO measure (measurepoint, val)"
							+ " VALUES(" + actMeasurePoint.getId() + ", " + String.valueOf(doubleValue) +  ")";
					log.debug("Double-Value to insert into database:" + insertSQL);
					stmt1.execute(insertSQL);
				}
				try {
					Thread.sleep(myConfig.getMeasureRequestInterval());
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		} catch (NamingException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		log.debug("Run is finishing ...");
	}

	public void stop() {
		myGoon = false;
	}
}
